#ifndef DATAOUTPUTMODELPARTGENERATOR_H_JM_20130219
#define DATAOUTPUTMODELPARTGENERATOR_H_JM_20130219
/// @file DataOutputModelPartGenerator.h
/// Generator casti modelu - time report + vystup dat z vypoctu + ukoncenie 
/// vypoctu.
#include "../generators/ModelGenerator.h"
#include "../generators/Slices.h"

namespace jm4bbx {
	/// Generator casti modelu - time report + vystup dat z vypoctu + ukoncenie 
	/// vypoctu.
	class  DataOutputModelPartGenerator {
	public:
		/// Prida potrebne boxy do generatoru modelu.
		/// @param mg generator modelu, ktoremu sa pridavaju boxy pre vystup dat
		/// @param outputBoxName meno vystupnych boxov, kt. sa pridavaju
		/// @param outputCount pocet vystupnych boxov resp. stupen paralelizacie
		void addBoxes(ModelGenerator* mg, const std::string& outputBoxName, 
				const std::string& outputForm, int outputCount) {

				outputCount_ = outputCount;

				timerReportBox_ = mg->addBox("TIMER_REPORT", 
					genBoxParam("signal_in", outputCount) + 
					genBoxParam("signal_out", outputCount)+
					genBoxParam("time_report", 1));


				outputBoxes_ = mg->addBox(outputBoxName, 
					genBoxParam("signal_in", 1) + 
					genBoxParam("signal_out", 1) +
					genBoxParam("form", outputForm) 
					/*+ genBoxParam("Psss", 1)*/, outputCount);

				endMergeBox_ = mg->addBox("SIGNAL_MERGE", 
					genBoxParam("signal_in", outputCount));
		}

		/// Pridanie rezov do generatoru modelu, kde rezy urcujucich spojenia 
		/// boxov pre vystup dat a ukoncenie vypoctu.
		/// @param mg generator modelu, ktoremu sa pridavaju rezy spojeni
		void addSlices(ModelGenerator* mg) {

			mg->addSlice( new ForkSlice(timerReportBox_->getBoxId(), 
				outputBoxes_->getBoxIds(), outputCount_, S_O, S_I));

			//// koniec vypoctu
			mg->addSlice(new MergeSlice(outputBoxes_->getBoxIds(), 
				endMergeBox_->getBoxId(), outputCount_, S_O, S_I));

			mg->addSlice(new PlainSlice(endMergeBox_->getBoxId(), 
				mg->getModelOutputId(), S_O, D_I));
		}

		BoxDescriptorPtr getOutputBoxes() { return outputBoxes_; }
		BoxDescriptorPtr getTimerReportBox() { return timerReportBox_; }
	private:
		BoxDescriptorPtr outputBoxes_;		
		BoxDescriptorPtr endMergeBox_;
		BoxDescriptorPtr timerReportBox_;
		
		size_t outputCount_;
	};

} // namespace jm4bbx


#endif
